package com.ojoin.trade.supplyloan_core.web.service.impl;

import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ojoin.trade.supplyloan_core.web.domain.*;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.ojoin.trade.bpm.web.domain.Bpm;
import com.ojoin.trade.bpm.web.service.BpmTaskService;
import com.ojoin.trade.bpm.web.support.ProcessMessageVO;
import com.ojoin.trade.common.Constants;
import com.ojoin.trade.common.constdef.IConstDef;
import com.ojoin.trade.common.exception.BusinessException;
import com.ojoin.trade.common.utils.BeanMapUtils;
import com.ojoin.trade.common.utils.CommonUtils;
import com.ojoin.trade.common.utils.FileUploadUtils;
import com.ojoin.trade.common.utils.Html2PDFAsianUtil;
import com.ojoin.trade.common.utils.LogUtils;
import com.ojoin.trade.common.utils.MoneyUtil;
import com.ojoin.trade.common.utils.SMSSendUtil;
import com.ojoin.trade.common.utils.TimeUtils;
import com.ojoin.trade.common.utils.UUIDUtils;
import com.ojoin.trade.common.utils.json.JSONUtils;
import com.ojoin.trade.common.web.dao.BaseDao;
import com.ojoin.trade.common.web.domain.AccountInfoVO;
import com.ojoin.trade.common.web.domain.NotificationTemplate;
import com.ojoin.trade.common.web.domain.Pair;
import com.ojoin.trade.common.web.domain.TbUploadFile;
import com.ojoin.trade.common.web.service.TbUploadFileService;
import com.ojoin.trade.common.web.service.impl.BaseServiceImpl;
import com.ojoin.trade.common.web.service.impl.NotificationTemplateService;
import com.ojoin.trade.common_core.web.domain.MerchantUserInfo;
import com.ojoin.trade.common_core.web.domain.TbMerchantInfo;
import com.ojoin.trade.common_core.web.domain.TbMerchantUser;
import com.ojoin.trade.common_core.web.service.AccountBaseService;
import com.ojoin.trade.common_core.web.service.BranchBaseService;
import com.ojoin.trade.common_core.web.service.MerchantUserBaseService;
import com.ojoin.trade.common_core.web.service.TbMerchantInfoBaseService;
import com.ojoin.trade.common_core.web.service.impl.DataVersionValidationService;
import com.ojoin.trade.supplyloan_core.constdef.ISLConstDef;
import com.ojoin.trade.supplyloan_core.web.dao.TbSlLoanApplicationDao;
import com.ojoin.trade.supplyloan_core.web.service.TbSlBankaccService;
import com.ojoin.trade.supplyloan_core.web.service.TbSlCreditCtrollService;
import com.ojoin.trade.supplyloan_core.web.service.TbSlLoanApplicationService;
import com.ojoin.trade.supplyloan_core.web.service.TbSlLoanCreditService;
import com.ojoin.trade.supplyloan_core.web.service.TbSlPlatformInfoService;
import com.ojoin.trade.supplyloan_core.web.service.TbSlPlatformUserService;

@Service
public class TbSlLoanApplicationServiceImpl extends
		BaseServiceImpl<TbSlLoanApplication> implements
		TbSlLoanApplicationService {
	
	private final static Logger log=LoggerFactory.getLogger(TbSlLoanApplicationServiceImpl.class);
	
	@Autowired
	private TbSlLoanApplicationDao dao;

	@Autowired
	private MerchantUserBaseService userservice;
	
	@Autowired
	private TbMerchantInfoBaseService merchantinfoservice;
	
	@Autowired
	private AccountBaseService accountService;
	
	@Autowired
	private TbSlLoanCreditService creditService;
	
	@Autowired
	private TbSlPlatformUserService platformuserService;

	@Autowired
	private TbSlPlatformInfoService platforminfoService;
	
	@Autowired
	private DataVersionValidationService validateservice;

	@Autowired
	private TbSlBankaccService bankaccService;
	
	@Autowired
	private BranchBaseService branchService;
	
	@Autowired
	private BpmTaskService bpmTaskService;

    @Autowired
    private TbSlCreditCtrollService tbSlCreditCtrollService;
	
    @Autowired
    private TbUploadFileService uploadFileService;
	
  	@Autowired
  	private TaskService taskService;
  	
    @Autowired
    private NotificationTemplateService notificationTemplateService;
    
	@Override
	protected BaseDao<TbSlLoanApplication> getBaseDao() {
		return dao; // To change body of implemented methods use File | Settings
					// | File Templates.
	}


	@Override
	public int insertTbSlApplication(int joinuserid)
			throws BusinessException {
		LogUtils.getSlloanLog().info(
				"待新增供应链贷款申请记录. joinuserid->" + joinuserid);
		
		TbSlLoanApplication existSLLoanVO = this.queryTbSlApplicationByJoinId(joinuserid);
		if (existSLLoanVO != null) {
			LogUtils.getSlloanLog().info(
					"不用新增，已存在joinuserid->" + existSLLoanVO.getIdOfTbMerchantUser() + "的供应链贷款申请记录. appvo->" + JSONUtils.toJSONString(existSLLoanVO));
			return existSLLoanVO.getId();
		}
		
		TbSlLoanApplication appvo=new TbSlLoanApplication();
		appvo.setIdOfTbMerchantUser(joinuserid);
		appvo.setCreaitApplyDate(TimeUtils.getCurDate());
		appvo.setLoanstatus(ISLConstDef.SLLOANSTATUS_INIT);
		return this.getBaseDao().insert(appvo);

	}

	@Override
	public List<TbSlLoanApplicationInfoVO> queryAllTbSlApplication()
			throws BusinessException {

		return ((TbSlLoanApplicationDao) this.getBaseDao())
				.queryAllTbSlApplication();
	}

	@Override
	public TbSlLoanApplication queryTbSlApplicationByJoinId(
			int id_of_tb_merchant_user) throws BusinessException {
		return ((TbSlLoanApplicationDao) this.getBaseDao())
				.queryTbSlApplicationByJoinId(id_of_tb_merchant_user);
	}

	@Override
	public void updateVagueCredit(TbSlLoanApplication vo, String taskid, String processid)
			throws BusinessException {
		LogUtils.getSlloanLog().info(
				"供应链贷款模糊授信. " + BeanMapUtils.getString(vo));
		validateservice.validateVO(vo.getId(),
				new TbSlLoanApplication().getTableName(), vo.getRowUpdateTime());

		//校验字段是否为空
		List<String> validFieldNames = new ArrayList<String>();
		validFieldNames.add("id");
		validFieldNames.add("idOfTbMerchantUser");
//		validFieldNames.add("discount");
		validFieldNames.add("rate");
		validFieldNames.add("fee");
		validFieldNames.add("loanPeriod");
//		validFieldNames.add("creditEndDate");
		validFieldNames.add("maxAmount");
		validFieldNames.add("idOfTbMerchantUserOfCreditor");
		validFieldNames.add("rowUpdateTime");
		List<Pair> applyValidBean = CommonUtils.beanValid(vo, validFieldNames);
		if(CollectionUtils.isNotEmpty(applyValidBean)){
			throw new BusinessException((String) ((Pair)(applyValidBean.get(0))).second);
		}
		
		vo.setLoanstatus(ISLConstDef.SLLOANSTATUS_CREDITED);
		vo.setCreditType(ISLConstDef.SLLOAN_CREDITTYPE_VAGUE);
		
		((TbSlLoanApplicationDao) this.getBaseDao()).updateByPrimaryIdAndJoinid(vo);
		
		//驱动授信流程
		Map<String,Object> taskVars = new HashMap();
		taskVars.put("pass", "1");
		TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(vo.getIdOfTbMerchantUser());
		taskVars.put("title", infovo.getMchName());
		runYWZYBpmProcessByVar(vo.getIdOfTbMerchantUserOfCreditor(), taskid, processid, taskVars, "模糊授信通过");

	}
	
	@Override
	public void updateCredit(TbSlLoanApplication vo) throws BusinessException {
		LogUtils.getSlloanLog().info(
				"供应链贷款授信修改. " + BeanMapUtils.getString(vo));
		validateservice.validateVO(vo.getId(),
				new TbSlLoanApplication().getTableName(), vo.getRowUpdateTime());

		((TbSlLoanApplicationDao) this.getBaseDao()).updateByPrimaryIdAndJoinid(vo);
	}

	@Override
	public void updateGenerateMaterial(int joinuserid) throws BusinessException {
		TbSlLoanApplication slapplyvo = this.queryTbSlApplicationByJoinId(joinuserid);
		if (slapplyvo == null)
			throw new BusinessException("joinuserid->" + joinuserid + "对应的供应链贷申请记录为空，请检查.");
		
		String contactno = getContractNO(slapplyvo.getIdOfTbMerchantUser());
		
		String contractfilepath = generateContractFile(contactno, slapplyvo);
		// 取相对路径
		contractfilepath = ISLConstDef.slcontractGenFileDir + File.separator
				+ FileUploadUtils.getFileNameFromPath(contractfilepath);

		Map<String, Object> paramap = new HashMap<String, Object>();
		paramap.put("id", slapplyvo.getId());
		paramap.put("materialDownload", contractfilepath);
		paramap.put("materialNo", contactno);
		((TbSlLoanApplicationDao) this.getBaseDao()).update(paramap);
	}

	// 根据相关参数生成保理合同
	private String generateContractFile(String contactno, TbSlLoanApplication slapplyvo)
			throws BusinessException {

		String filePath = FileUploadUtils.getDefaultBaseDir() + File.separator
				+ ISLConstDef.slcontractGenFileDir;

		LogUtils.getSlloanLog().info(
				"生成保理合同，" + "joinuserid->" + slapplyvo.getIdOfTbMerchantUser() + ", filePath->"
						+ filePath);

//		String mhtno = userservice.queryPayUserByJoinUserID(joinuserid);
//		MerchantUserInfo uservo = userservice.queryMerchantUserVOByMhtno(mhtno);
		TbMerchantInfo uservo = merchantinfoservice.queryInfoByJoinId(slapplyvo.getIdOfTbMerchantUser());
		if (uservo == null)
			throw new BusinessException("申请商户joinuserid->" + slapplyvo.getIdOfTbMerchantUser() + "对应的实名认证信息为空，请检查.");
		
		TbMerchantInfo creditorvo = merchantinfoservice.queryInfoByJoinId(slapplyvo.getIdOfTbMerchantUserOfCreditor());
		if (creditorvo == null)
			throw new BusinessException("保理公司joinuserid->" + slapplyvo.getIdOfTbMerchantUserOfCreditor() + "对应的实名认证信息为空，请检查.");
		
		//TODO:remove dev 生成保理合同的时候不开户
//		AccountInfoVO accountinfovo ;//accountService.querySettleAccountChangeInfo(mhtno);
//		accountinfovo=CommonUtils.creatRandomObject(AccountInfoVO.class);
		
		//此处的分隔符必须使用/,不可使用File.separator，否则取到的path为空
		InputStream templatefilePath=this.getClass().getResourceAsStream("/SLload/SLcontract.html");
		
		String contractFilePath = generateSLContractFileByMhtno(contactno, uservo, creditorvo, 
						null, slapplyvo, filePath, templatefilePath);

		LogUtils.getSlloanLog().info("生成保理合同，文件路径->" + contractFilePath);
		return contractFilePath;
	}

	/**
	 * 生成指定商户的保理合同pdf文件
	 * 
	 * @param mhtvo
	 * @return
	 */
	private String generateSLContractFileByMhtno(String contactno, 
			TbMerchantInfo mhtvo, TbMerchantInfo creditorvo,
			AccountInfoVO accountinfovo, TbSlLoanApplication slapplyvo,
			String targetPDFFileFolder, InputStream templatefilePath)
			throws BusinessException {

		HashMap<String, String> replaceMap = new HashMap<String, String>();
		replaceMap.put("#contractno#", contactno);
		replaceMap.put("#mhtname#", mhtvo.getMchName());
		replaceMap.put("#name#", mhtvo.getName());
		replaceMap.put("#mobile#", mhtvo.getMobile());
		replaceMap.put("#businessname#", "有追索权保理业务");
		replaceMap.put("#discount#", slapplyvo.getDiscount());
//		replaceMap.put("#loan_period#", slapplyvo.getLoanPeriod());
//		replaceMap.put("#bankMan#", accountinfovo.getBankMan());
//		replaceMap.put("#bankName#", accountinfovo.getBankName());
//		replaceMap.put("#settleAccno#", accountinfovo.getSettleAccno());
		
		replaceMap.put("#creditorMchName#", creditorvo.getMchName());
		replaceMap.put("#creditorAddress#", creditorvo.getAddress());
		replaceMap.put("#creditorName#", creditorvo.getName());
		
		replaceMap.put("#rate#", slapplyvo.getRate());
		replaceMap.put("#renewed_servicefee#", slapplyvo.getRenewedServicefee());
		replaceMap.put("#renewed_rate#", slapplyvo.getRenewedRate());
		replaceMap.put("#penalty#", slapplyvo.getPenalty());
		replaceMap.put("#cardno#", mhtvo.getCertNo());
		replaceMap.put("#fee#", slapplyvo.getFee());

		String filePrefix = "SLload";
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
				"yyyyMMddHHmmss");
		String targetPDFFilename = filePrefix + "_"
				+ simpleDateFormat.format(new Date()) + "_"
				+ UUIDUtils.create();

		return new Html2PDFAsianUtil().generatePDFFileByMhtno(replaceMap, targetPDFFileFolder, targetPDFFilename, templatefilePath, filePrefix, contactno);
	}
	
	//组装生成保理合同编号
	private String getContractNO(int joinuserid) {
		TbSlLoanApplication applyvo = this.queryTbSlApplicationByJoinId(joinuserid);
		TbMerchantUser debtor = userservice.queryById(joinuserid);
		TbMerchantUser creditor = userservice.queryById(applyvo.getIdOfTbMerchantUserOfCreditor());
		String debtorShortName = debtor.getShortname();
		String creditorShortName = creditor.getShortname();

		//保理合同编号（年-资方代码-融方代码-编号（两位）例如：2015-QHXZ（前海现在）-PNLT（普宁联拓）-01（按合同数量延续））
		String contractNo = TimeUtils.getCurYear() + "-" + creditorShortName + "-" + debtorShortName + "-01"; // + contractNum;

		return contractNo;
	}
	
	@Override
	public void updateActiveSlLoan(int id, String material, String contract)
			throws BusinessException {
		Map<String, Object> paramap = new HashMap<String, Object>();
		paramap.put("id", id);
		paramap.put("material", material);
		paramap.put("contract", contract);
		((TbSlLoanApplicationDao) this.getBaseDao()).update(paramap);
	}

	@Override
	public long getCreditExpiredDays(int id_of_tb_merchant_user)
			throws BusinessException {

		TbSlLoanApplication vo = ((TbSlLoanApplicationDao) this.getBaseDao())
				.queryTbSlApplicationByJoinId(id_of_tb_merchant_user);
		if (vo == null) {
			throw new BusinessException("没有查询到该商户的贷款申请记录");
		}
		String creditEndDate = vo.getCreditEndDate();
		try {
			long days = TimeUtils.getDateSpaceOfDay(TimeUtils.getCurDate(),
                    creditEndDate);
			return days;
		} catch (Exception e) {
			e.printStackTrace();
			throw new BusinessException("计算用户授信期还有几天过期");
		}
	}

	@Override
	/*
	 * 根据id查询申请记录
	 */
	public TbSlLoanApplication queryTbSlApplicationByID(int id)
			throws BusinessException {
		return this.queryById(id);
	}

	@Override
	public int deleteTbSlApplicationByJoin(TbSlLoanApplication appvo)
			throws BusinessException {
		if (appvo.getIdOfTbMerchantUser() == 0) {
			throw new BusinessException("获取九盈用户id出错");
		}

		LogUtils.getSlloanLog().info(
				"删除九盈用户id. joinuserNo->" + appvo.getIdOfTbMerchantUser());
		((TbSlLoanApplicationDao) this.getBaseDao()).delete(appvo);
		return 0;
	}

	@Override
	public List<TbSLLoanTodoTaskVO> queryAdminUserTodoTaskList()
			throws BusinessException {
		LogUtils.getSlloanLog().info("查询供应链贷款后台管理员代办任务列表");
		List<TbSLLoanTodoTaskVO> selectList = ((TbSlLoanApplicationDao) this
				.getBaseDao()).queryAdminUserTodoTaskList();
		if (selectList == null || selectList.size() == 0)
			return null;

		return selectList;
	}

	@Override
	public List<TbSLLoanTodoTaskVO> queryOperatorTodoTaskList()
			throws BusinessException {
		LogUtils.getSlloanLog().info("查询保理员代办任务列表");
		List<TbSLLoanTodoTaskVO> selectList = ((TbSlLoanApplicationDao) this
				.getBaseDao()).queryOperatorTodoTaskList();
		if (selectList == null || selectList.size() == 0)
			return null;

		return selectList;
	}

	@Override
	public List<TbSlLoanApplicationInfoVO> querySLLoanAppInfoListByStatus(
			int loanstatus, Pageable page) throws BusinessException {
		return ((TbSlLoanApplicationDao) this.getBaseDao())
				.querySLLoanAppInfoListByStatus(loanstatus, page);

	}

	@Override
	public List<TbSlLoanApplicationStatVO> querySlLoanApplyStatListByStatus(
			int loanstatus, int joinuserid, Pageable page) throws BusinessException {
		return ((TbSlLoanApplicationDao) this.getBaseDao())
				.querySlLoanApplyStatListByStatus(loanstatus, joinuserid, page);

	}


	@Override
	public int updateLoanStatusByIdWithTs(int liveid, int joinuserid,
			int loanstatus, String clientTs) throws BusinessException {
		LogUtils.getSlloanLog().info(
				"更新指定申请记录的申请状态. liveid->" + liveid + ",loanstatus->" + loanstatus);

		validateservice.validateVO(liveid,
				new TbSlLoanApplication().getTableName(), clientTs);

		//TODO：1、开通基本户、金融户
//		String mhtNo = userservice.queryPayUserByJoinUserID(joinuserid);
//		accountService.openFinanceAccount(mhtNo);
		
		//2、更新
		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setId(liveid);
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setLoanstatus(loanstatus);

		int update = ((TbSlLoanApplicationDao) this.getBaseDao())
				.updateByPrimaryIdAndJoinid(vo);
		
		//更新上传文件状态为已提交
		uploadFileService.updateStatusById(CommonUtils.getInt(vo.getCreditCertificate()), IConstDef.UPLOADSTATUS_COMMITED);

		return update;
	}

	@Override
	public int updateLoanStatusAndMortgageByIdWithTs(int liveid, int joinuserid,
			int idOfTbMerchantUserOfCreditor,
			int loanstatus, int mortgageFlag, String mortgageInfo, 
			String creditEndDate, String taskid, String processid, String clientTs) throws BusinessException {
		LogUtils.getSlloanLog().info(
				"更新指定申请记录的申请状态. liveid->" + liveid + ",loanstatus->" + loanstatus);

		validateservice.validateVO(liveid,
				new TbSlLoanApplication().getTableName(), clientTs);

		//TODO：1、开通基本户、金融户
//		String mhtNo = userservice.queryPayUserByJoinUserID(joinuserid);
//		accountService.openFinanceAccount(mhtNo);

        //初始化提款的版本号

        tbSlCreditCtrollService.insertControllVo(joinuserid);
		//2、更新
		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setId(liveid);
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setLoanstatus(loanstatus);
		vo.setMortgageFlag(mortgageFlag);
		vo.setMortgageInfo(mortgageInfo);
		vo.setCreditEndDate(creditEndDate);

		int update =  ((TbSlLoanApplicationDao) this.getBaseDao())
				.updateByPrimaryIdAndJoinid(vo);
		
		//更新上传文件状态为已提交
		uploadFileService.updateStatusById(CommonUtils.getInt(mortgageInfo), IConstDef.UPLOADSTATUS_COMMITED);
			
		Map<String,Object> taskVars = new HashMap();
		taskVars.put("pass", "1");
		TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(joinuserid);
		taskVars.put("title", infovo.getMchName());
		runYWZYBpmProcessByVar(idOfTbMerchantUserOfCreditor, taskid, processid, taskVars, "合同审核通过");	
		
		return update;
	}

	@Override
	public int updateLoanStatusById(int joinuserid,
			int loanstatus) throws BusinessException {
		LogUtils.getSlloanLog().info(
				"更新指定申请记录的申请状态. joinuserid->" + joinuserid + ",loanstatus->" + loanstatus);

		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setLoanstatus(loanstatus);

		return ((TbSlLoanApplicationDao) this.getBaseDao())
				.updateByJoinid(vo);
	}
	
	@Override
	public int updateLoanStatusAndMemoById(int liveid, int joinuserid,
			int loanstatus, String memo, String clientTs)
			throws BusinessException {
		validateservice.validateVO(liveid,
				new TbSlLoanApplication().getTableName(), clientTs);

		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setId(liveid);
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setMemo(memo);
		vo.setLoanstatus(loanstatus);

		return ((TbSlLoanApplicationDao) this.getBaseDao())
				.updateByPrimaryIdAndJoinid(vo);
	}

	public void updateCreditInformationAndContract(int joinuserid,
			String creditInformation, String contractFilePath) throws BusinessException {
		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setContract(contractFilePath);
		vo.setCreditInformation(creditInformation);
		vo.setLoanstatus(ISLConstDef.SLLOANSTATUS_COMMITVAGUECREDIT);

		((TbSlLoanApplicationDao) this.getBaseDao())
				.updateByJoinid(vo);
	}
	
	// 用户上传上下游合同
	@Override
	public void updateContract(int joinuserid,
			String contractFilePath) throws BusinessException {
		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setContract(contractFilePath);
		vo.setLoanstatus(ISLConstDef.SLLOANSTATUS_COMMITCONTRACT);

		((TbSlLoanApplicationDao) this.getBaseDao())
				.updateByJoinid(vo);
	}

	//用户提交保理合同
	@Override
	public void updateMaterial(int joinuserid,
			String materialFileID,int slLoanId) throws BusinessException {
		
		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setMaterial(materialFileID);
		vo.setLoanstatus(ISLConstDef.SLLOANSTATUS_MATERIALCOMMITED);

		uploadFileService.updateStatusById(Integer.parseInt(materialFileID),IConstDef.UPLOADSTATUS_COMMITED);
		
		((TbSlLoanApplicationDao) this.getBaseDao()).updateByJoinid(vo);
		
		//授信流程实例id

		String creditProcessDefinitionId = ISLConstDef.creditProcessDefinitionKey;
		 //驱动流程实例
        String processid = querySLLoanAppProcInstIdById(slLoanId);
        Task taskUSER = taskService.createTaskQuery().processDefinitionKey(creditProcessDefinitionId).processInstanceId(processid).singleResult();
		if(null==taskUSER){
			LogUtils.error(log, "申请ID"+slLoanId+",流程失效");
			throw new BusinessException("流程失效");
		}
        bpmTaskService.claim(taskUSER.getId(), "sl_user");
		bpmTaskService.complete(taskUSER.getId(), taskUSER.getProcessInstanceId(), "用户确认签约", null);
    
	}

	/**
	 * 用户上传模糊授信信息
	 * 
	 */
	@Override
	public void updateCreditInformation(int joinuserid,
			String creditInformation) throws BusinessException {
		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setCreditInformation(creditInformation);
		vo.setLoanstatus(ISLConstDef.SLLOANSTATUS_COMMITVAGUECREDIT);

		((TbSlLoanApplicationDao) this.getBaseDao())
				.updateByJoinid(vo);
	}

	public String[] generateSLLoanApplyFile(int joinuserid, Integer bankacc, List<TbSlLoanCreditLog> creditlogList, String targetPDFFileFolder) throws BusinessException {
		if (creditlogList == null || creditlogList.size() == 0)
			throw new BusinessException("融资平台信息为空，请检查.");
		
		//查询已有融资编号的最大值
		String creditMaxcode = creditService.selectCreditLoanCountByJoinid(joinuserid);
		
		//得到融资编号中的数字最大值
		int creditcount = 0;
		if (!StringUtils.isEmpty(creditMaxcode)) {
			creditcount = CommonUtils.getInt(StringUtils.right(creditMaxcode, 3));
		}
		
		TbSlLoanApplication applyvo = this.queryTbSlApplicationByJoinId(joinuserid);
		if (applyvo == null)
			throw new BusinessException("用户ID->" + joinuserid + "申请信息为空，请检查.");
		
		TbMerchantInfo debtor = merchantinfoservice.queryInfoByJoinId(joinuserid);
		if (debtor == null)
			throw new BusinessException("用户ID->" + joinuserid + "的实名信息为空，请检查.");
		
		TbMerchantInfo creditor = merchantinfoservice.queryInfoByJoinId(applyvo.getIdOfTbMerchantUserOfCreditor());
		if (creditor == null)
			throw new BusinessException("用户ID->" + joinuserid + "的放款方实名信息为空，请检查.");
		
		HashMap<String, String> replaceMap = new HashMap<String, String>();
		replaceMap.put("#loanapplyDate#", applyvo.getCreaitApplyDate());
		replaceMap.put("#applyDate#", TimeUtils.getCurDateInFile());
		replaceMap.put("#debtorFullName#", debtor.getMchName());
		replaceMap.put("#creditorFullName#", creditor.getMchName());

		//保理合同编号（年-资方代码-融方代码-编号（两位）例如：2015-QHXZ（前海现在）-PNLT（普宁联拓）-01（按合同数量延续））
//		String contractNo = getContractNO(joinuserid);
		String contractNo = applyvo.getMaterialNo();//生成保理合同时保存编号至materialno字段
		
		replaceMap.put("#contractNo#", contractNo);
		replaceMap.put("#loanPeriod#", applyvo.getLoanPeriod());
		
		//贷款编号：合同编号-编号（按贷款次数顺延）。如：2015-QHXZ-PNLT-01-001
		//返回的returnStr[0]是html内容，其余是每条贷款生成的贷款编号
		String[] returnStr = getCreditPartHTML(creditlogList, creditcount, contractNo);
		replaceMap.put("#creditPartHtml#", returnStr[0]);
		
		creditlogList.get(0).setIdOfBankAcc(bankacc);
		String[] bankinfos = getBankbranchAndAccountByCreditLog(creditlogList.get(0).getUserIdOfIPayNowOfDebtor(), bankacc);
		
		replaceMap.put("#accountname#", bankinfos[0]); //银行账户户名
		replaceMap.put("#bankname#", bankinfos[1]); //开户行
		replaceMap.put("#accountno#", bankinfos[2]); //账户
		
		//此处的分隔符必须使用/,不可使用File.separator，否则取到的path为空
		InputStream templatefilePath=this.getClass().getResourceAsStream("/SLload/SLLoanApply.html");
		String contractFilePath = generatePDFFile("slloanapply", replaceMap, targetPDFFileFolder, templatefilePath);
		returnStr[0] = contractFilePath;
		
		return returnStr;
	}

	private String[] getBankbranchAndAccountByCreditLog(String userIdOfIPayNowOfDebtor, Integer idOfBankAcc) {
		String[] bankinfoStr = new String[3];
		//TODO:正式环境中userinfo如果为空表示没有开通金融户，需要报错提示
		TbMerchantInfo userinfo = merchantinfoservice.queryInfoByMhtno(userIdOfIPayNowOfDebtor);
		if (userinfo != null) {
			bankinfoStr[0] = userinfo.getMchName(); //银行账户户名
		} else {
			bankinfoStr[0] = "  ";
		}
		//填入前台选择的账户信息
		if (idOfBankAcc == null) {
			bankinfoStr[1] = "中国民生银行股份有限公司厦门湖里支行"; //开户行
			if (userinfo != null && userinfo.getBankAccount() != null) {
				bankinfoStr[2] = userinfo.getBankAccount() + "   "; //账户
			} else {
				bankinfoStr[2] = "  ";
			}
		} else {
			TbSlBankacc bankaccVO = bankaccService.queryById(idOfBankAcc);
			if (bankaccVO != null) {
				String displayBranchNo=branchService.queryDisplayBranchNo(String.valueOf(bankaccVO.getUnionBankNo()));
				bankinfoStr[1] = displayBranchNo; //开户行
				bankinfoStr[2] = bankaccVO.getBankacc(); //账户
			} else {
				bankinfoStr[1] = "  ";
				bankinfoStr[2] = "  ";
			}
		}
		
		return bankinfoStr;
	}

	private String[] getCreditPartHTML(List<TbSlLoanCreditLog> creditlogList, 
			int creditcount, String contractNo) throws BusinessException {
		String[] returnStr = new String[creditlogList.size() + 1];
		long totalamount = 0;
		
		StringBuffer str =  new StringBuffer();
		int linenum = creditlogList.size() + 2;
		str.append("<tr>"+
				"<td width=\"30%\" rowspan=\"" + linenum + "\" align=\"right\" class=\"linetd\"  >申请提现总金额：</td>"+
				"<td class=\"linetd\" width=\"20%\">融资编号</td>"+
				"<td class=\"linetd\" width=\"10%\">平台</td>"+
				"<td class=\"linetd\" width=\"10%\">日利率(%)</td>"+
				"<td class=\"linetd\" width=\"15%\">金额(元)</td>"+
				"<td class=\"linetd\" width=\"15%\">到期日</td>"+
				"</tr>");
		
		for(int i = 1; i<= creditlogList.size(); i++) {
			TbSlLoanCreditLog logvo = creditlogList.get(i-1);
			creditcount = creditcount + 1;
			String loanNo = contractNo + "-" + StringUtils.right("00" + creditcount, 3);
			returnStr[i] = loanNo;
			
			int idOfPlatform = logvo.getIdOfPlatform();
			TbSlPlatformUser uservo = platformuserService.queryById(idOfPlatform);
			String platformCnname = platforminfoService.queryByName(uservo.getPlatformName()).getPlatformCnname();
			String amount = logvo.getAccountDelta();
			String amountRMB = MoneyUtil.getDisplayRMB(amount);
			
			String expiredate = "";
			try {
				expiredate = TimeUtils.getDateAfterDays(logvo.getCreditTime(), CommonUtils.getInt(uservo.getLoanPeriod()));
			} catch (Exception e) {
				throw new BusinessException("融资到期日期获取失败，请检查.");
			}
			
			str.append("<tr>" +
				"<td class=\"linetd\" width=\"20%\">" + loanNo + "</td>"+
				"<td class=\"linetd\" width=\"10%\">" + platformCnname + "</td>"+
				"<td class=\"linetd\" width=\"10%\">" + logvo.getRate() + "</td>"+
				"<td class=\"linetd\" width=\"15%\">" + amountRMB + "</td>"+
				"<td class=\"linetd\" width=\"15%\">" + expiredate + "</td>"+
				"</tr>");
			
			totalamount += getLongAmount(amount);
		}
		String totalamountStr = MoneyUtil.getDisplayRMB(totalamount + "");
		str.append("<tr><td colspan=\"5\" class=\"linetd\">总金额合计：" + totalamountStr + "元</td></tr>");
		
		returnStr[0] = str.toString();
		
		return returnStr;
	}
	
	
	private String getPaymentOrderCreditPartHTML(List<TbSlStatusCreditLogVo> creditlogList) throws BusinessException {
		long totalamount = 0;
		
		StringBuffer str =  new StringBuffer();
		int linenum = creditlogList.size() + 2;
		str.append("<tr>"+
				"<td class=\"linetd\" width=\"20%\" align=\"right\" rowspan=\"" + linenum + "\" >保理融资金额：</td>"+
				"<td class=\"linetd\" width=\"30%\">融资编号</td>"+
				"<td class=\"linetd\" width=\"20%\">融资金额(元)</td>"+
				"<td class=\"linetd\" width=\"30%\">融资年化收益(%)</td>"+
				"</tr>");
		
		for(int i = 1; i<= creditlogList.size(); i++) {
			TbSlStatusCreditLogVo logvo = creditlogList.get(i-1);
			
			String loanNo = logvo.getCode();
			String rate = logvo.getRate();
			String amount = logvo.getAccountDelta();
			String amountRMB = MoneyUtil.getDisplayRMB(amount);
			
			BigDecimal rateStr = new BigDecimal(rate).multiply(new BigDecimal(360));
			
			str.append("<tr>" +
				"<td class=\"linetd\" width=\"30%\">" + loanNo + "</td>"+
				"<td class=\"linetd\" width=\"20%\">" + amountRMB + "</td>"+
				"<td class=\"linetd\" width=\"30%\">" + rateStr.toString() + "</td>"+
				"</tr>");
			
			totalamount += getLongAmount(amount);
		}
		String totalamountStr = MoneyUtil.getDisplayRMB(totalamount + "");
		str.append("<tr><td colspan=\"3\" class=\"linetd\">保理融资总额：人民币" + totalamountStr + "元</td></tr>");
		
		return str.toString();
	}
	
	private long getLongAmount(String catchamount) {
		return new BigDecimal(Double.valueOf(catchamount)).longValue();
	}
    @Override
    public Long getCreditExpireDays(int joinid) throws BusinessException {

        TbSlLoanApplication vo = ((TbSlLoanApplicationDao) this.getBaseDao())
                .queryTbSlApplicationByJoinId(joinid);
        if(vo==null){
            return null;
        }else{
            String credit_enddate=vo.getCreditEndDate();
            if(StringUtils.isEmpty(credit_enddate) && credit_enddate.length() < 10){
                return null;
            }
            try{
            	credit_enddate = credit_enddate.substring(credit_enddate.length() - 10);
            long days=TimeUtils.getDateSpaceOfDay(TimeUtils.getCurDate(), credit_enddate);
                return new Long(days);
            }catch (Exception e){
                throw new BusinessException("计算用户的授信到期日有误");
            }
        }
    }


	private String generatePDFFile(String filePrefix, HashMap<String, String> replaceMap, String targetPDFFileFolder,
			InputStream templatefilePath) throws BusinessException {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
				"yyyyMMddHHmmss");
		String targetPDFFilename = filePrefix + "_"
				+ simpleDateFormat.format(new Date()) + "_"
				+ UUIDUtils.create();
		return new Html2PDFAsianUtil().generatePDFFileByMhtno(replaceMap, targetPDFFileFolder,
				targetPDFFilename, templatefilePath, filePrefix, null);
	}

	@Override
	public void updateAgreeSLLoanFee(int joinuserid) throws BusinessException {
		updateLoanStatusById(joinuserid, ISLConstDef.SLLOANSTATUS_USERCOMFIRMED);
		updateGenerateMaterial(joinuserid);
	}

	@Override
	public List<TbSlLoanApplicationInfoVO> queryCreditedSLLoanAppInfoList(
			int loanstatus, Pageable page) throws BusinessException {
		return ((TbSlLoanApplicationDao) this.getBaseDao())
				.queryCreditedSLLoanAppInfoList(loanstatus, page);
	}

	@Override
	public TbSlLoanCreditAggVO selectAllSLLoanCreditAggVOByJoinID(int joinuserid) throws BusinessException {
		try {
			TbMerchantUser uservo = userservice.queryById(joinuserid);
			TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(joinuserid);
			TbSlLoanApplication applyvo = queryTbSlApplicationByJoinId(joinuserid);
			List<TbSlPlatformUserVO> platformuserList = platformuserService
					.selectAllPlatformUserListByJoinID(joinuserid, null);
			
			TbSlLoanCreditAggVO aggvo = new TbSlLoanCreditAggVO();
			aggvo.setShortname(uservo.getShortname());
			aggvo.setFullname(infovo.getMchName());
			aggvo.setMobile(infovo.getMobile());
			aggvo.setApplyvo(applyvo);
			
			if (applyvo.getLoanstatus() != ISLConstDef.SLLOANSTATUS_MATERIALPASSED) {
				aggvo.setPlatformuserList(platformuserList);
			} else if (platformuserList != null && platformuserList.size() > 0) {
				List<TbSlPlatformUserVO> platformuserList_end = new ArrayList<TbSlPlatformUserVO>();
				for (TbSlPlatformUserVO pvo : platformuserList) {
					if (pvo.getEnableFlag().equals(ISLConstDef.PLATFORM_STATUS_ENABLED)) {
						platformuserList_end.add(pvo);
					}
				}
				aggvo.setPlatformuserList(platformuserList_end);
			}
			return aggvo;
		} catch (Exception e) {
			LogUtils.getSlloanLog().error(e.getMessage());
			throw new BusinessException("查询join用户" + joinuserid
					+ "的所有授信信息出错,请重试");
		}
	}
	
	public String generateSLPaymentOrder(int joinuserid, int  id, String procInsId) throws BusinessException {
		TbSlLoanApplication applyvo = this.queryTbSlApplicationByJoinId(joinuserid);
		TbMerchantInfo debtor = merchantinfoservice.queryInfoByJoinId(joinuserid);
		TbMerchantInfo creditor = merchantinfoservice.queryInfoByJoinId(applyvo.getIdOfTbMerchantUserOfCreditor());
		
		HashMap<String, String> replaceMap = new HashMap<String, String>();
		replaceMap.put("#paymentDate#", TimeUtils.getCurDateInFile());
		replaceMap.put("#debtorFullName#", debtor.getMchName());
		replaceMap.put("#creditorFullName#", creditor.getMchName());
		replaceMap.put("#contractNo#", applyvo.getMaterialNo());
		
		List<TbSlStatusCreditLogVo> creditlogList = creditService.queryCreditByProcessid(id);
		if (creditlogList == null || creditlogList.size() == 0) 
			throw new BusinessException("id->" + id + "查不到对应的融资记录.");
		String[] bankinfos = getBankbranchAndAccountByCreditLog(creditlogList.get(0).getUserIdOfIPayNowOfDebtor(), creditlogList.get(0).getIdOfBankAcc());
		replaceMap.put("#branchname#", bankinfos[1]); //开户行
		replaceMap.put("#bankaccount#", bankinfos[2]); //账户
		
		String creditStr = getPaymentOrderCreditPartHTML(creditlogList);
		replaceMap.put("#creditPartHtml#", creditStr);
		
		String historyStr = getHistoicFlowListHTML(procInsId);
		replaceMap.put("#histoicFlowListHTML#", historyStr);
		
		//此处的分隔符必须使用/,不可使用File.separator，否则取到的path为空
		InputStream templatefilePath=this.getClass().getResourceAsStream("/SLload/SLPaymentOrder.html");
		
		String targetPDFFileFolder = FileUploadUtils.getDefaultBaseDir()
                + File.separator + ISLConstDef.slLoanPaymentOrderDir;
		String contractFilePath = generatePDFFile("slPaymentOrder", replaceMap, targetPDFFileFolder, templatefilePath);
		
		String downloadpath = ISLConstDef.slLoanPaymentOrderDir
                + File.separator + FileUploadUtils.getFileNameFromPath(contractFilePath);
		
		TbUploadFile uploadFileVO=new TbUploadFile();
        uploadFileVO.setDownloadPath(downloadpath);
        uploadFileVO.setOriginalName(joinuserid + "-" + TimeUtils.getCurDate() + "-" + IConstDef.DOWNLOAD_PAYMENTORDER);
        uploadFileVO.setIdOfTbMerchantUser(joinuserid);
        uploadFileVO.setStatus(IConstDef.UPLOADSTATUS_COMMITED);
        uploadFileVO.setUploadOperator(String.valueOf(joinuserid));
        uploadFileVO.setFileType(ISLConstDef.SUPPLY_PAYMENT_NOTICE);
        uploadFileService.insert(uploadFileVO);
        
        String payment_notice = uploadFileVO.getId() + "";
        Map<String, Object> parammap = new HashMap<String, Object>();
        parammap.put("paymentNotice", payment_notice);
        for (TbSlStatusCreditLogVo creditlogvo : creditlogList) {
        	parammap.put("id", creditlogvo.getId());
        	creditService.updateTbSlLoanCredit(parammap);
        }
        
		return downloadpath;
	}

	private String getHistoicFlowListHTML(String procInsId) throws BusinessException {
		List<Bpm> histoicFlowList = bpmTaskService.histoicFlowList(procInsId, null, null);
		StringBuffer str =  new StringBuffer();
		if (histoicFlowList == null || histoicFlowList.size() == 0) {
			str.append("<tr><td>没有查询到审批历史记录</td></tr>");
		} else {
			str.append("<tr>"+
					"<td class=\"linetd\" width=\"10%\">执行环节</td>"+
					"<td class=\"linetd\" width=\"20%\">执行人</td>"+
					"<td class=\"linetd\" width=\"20%\">开始时间</td>"+
					"<td class=\"linetd\" width=\"20%\">结束时间</td>"+
					"<td class=\"linetd\" width=\"20%\">提交意见</td>"+
					"<td class=\"linetd\" width=\"10%\">任务历时</td>"+
					"</tr>");
			for(Bpm bpm : histoicFlowList) {
				String taskname = bpm.getTaskName();
				String assname = bpm.getAssigneeName();
				String createdate = bpm.getTaskCreateDate() == null ? "--" : TimeUtils.getDateString(bpm.getTaskCreateDate());
				String enddate = bpm.getTaskEndDate() == null ? "--" : TimeUtils.getDateString(bpm.getTaskEndDate());
				String comment = bpm.getComment() == null ? "--" : bpm.getComment();
				String durtime = bpm.getDisplyaDurationTime();
				str.append("<tr>" +
						"<td class=\"linetd\" width=\"10%\">" + taskname + "</td>"+
						"<td class=\"linetd\" width=\"20%\">" + assname + "</td>"+
						"<td class=\"linetd\" width=\"20%\">" + createdate + "</td>"+
						"<td class=\"linetd\" width=\"20%\">" + enddate + "</td>"+
						"<td class=\"linetd\" width=\"20%\">" + comment + "</td>"+
						"<td class=\"linetd\" width=\"10%\">" + durtime + "</td>"+
					"</tr>");
			}
		}
		return str.toString();
	}
	
	public String generateSLRenewedApply(int joinuserid, int creditlogid) throws BusinessException {
		String targetPDFFileFolder = FileUploadUtils.getDefaultBaseDir()
                + File.separator + ISLConstDef.slLoanRenewedApplyDir;
		
		TbSlLoanApplication applyvo = this.queryTbSlApplicationByJoinId(joinuserid);
		TbMerchantInfo debtor = merchantinfoservice.queryInfoByJoinId(joinuserid);
		TbMerchantInfo creditor = merchantinfoservice.queryInfoByJoinId(applyvo.getIdOfTbMerchantUserOfCreditor());
		
		HashMap<String, String> replaceMap = new HashMap<String, String>();
		replaceMap.put("#debtorFullName#", debtor.getMchName());
		replaceMap.put("#creditorFullName#", creditor.getMchName());
        TbSlLoanCreditLog creditlog= creditService.queryCreditLogById(creditlogid);
		replaceMap.put("#contractNo#", applyvo.getMaterialNo());
		replaceMap.put("#applyNo#", creditlog.getCode());
		replaceMap.put("#creditDate#", creditlog.getRealLoanTime());
		
		String accountDelta = CommonUtils.getFenByString(creditlog.getTotalNotPaybackAmount());
		BigDecimal numberOfMoney = new BigDecimal(accountDelta);
        String accountDeltaCN = MoneyUtil.number2CNMontrayUnit(numberOfMoney);
        replaceMap.put("#accountDelta#", accountDeltaCN);
	    
		//此处的分隔符必须使用/,不可使用File.separator，否则取到的path为空
		InputStream templatefilePath=this.getClass().getResourceAsStream("/SLload/SLRenewedApply.html");
		String contractFilePath = generatePDFFile("slRenewedApply", replaceMap, targetPDFFileFolder, templatefilePath);
		
		return contractFilePath;
	}
	
    @Override
    public SlCreditRenewedVo queryRenewedInfoByCredit(Integer id, Integer joinid) throws BusinessException {
        if(CommonUtils.isEmpty(id)){
            throw new BusinessException("待展期的贷款不能为空");
             }
         if(CommonUtils.isEmpty(joinid)){
             throw new BusinessException("商户不能为空");
         }
        SlCreditRenewedVo slCreditRenewedVo=new SlCreditRenewedVo();
        TbSlLoanApplication appvo=queryTbSlApplicationByJoinId(joinid);
        TbSlLoanCreditLog creditLog=creditService.queryCreditLogById(id);
        String renewedAmountRate=appvo.getRenewedServicefee();
        if(CommonUtils.isEmpty(renewedAmountRate)){
            renewedAmountRate="0";
        }
        slCreditRenewedVo.setRenewedAmountRate(renewedAmountRate);
        String totalNotPaybackAmount=creditLog.getTotalNotPaybackAmount();
        BigDecimal renewedamount=new BigDecimal(totalNotPaybackAmount).multiply((new BigDecimal(renewedAmountRate)).divide(new BigDecimal(100)));
        slCreditRenewedVo.setRenewedAmount(renewedamount.toString());
        String fee=creditLog.getFee();
        if(CommonUtils.isEmpty(fee)){
            fee="0";
        }
        String rate=creditLog.getRate();
        if(CommonUtils.isEmpty(rate)){
            rate="0";
        }
        String renewedFee=appvo.getRenewedFee();
        if(CommonUtils.isEmpty(renewedFee)){
            renewedFee="0";
        }
        String renewedRate=appvo.getRenewedRate();
        if(CommonUtils.isEmpty(renewedRate)){
            renewedRate="0";
        }
        BigDecimal renewedfee=new BigDecimal(fee).multiply(new BigDecimal(1).add(new BigDecimal(renewedFee).divide(new BigDecimal(100))));
        BigDecimal renewedrate=new BigDecimal(rate).multiply(new BigDecimal(1).add(new BigDecimal(renewedRate).divide(new BigDecimal(100))));
        slCreditRenewedVo.setRenewedfee(renewedfee.toString());
        slCreditRenewedVo.setRenewedRate(renewedrate.toString());
        slCreditRenewedVo.setAmount(creditLog.getTotalNotPaybackAmount());
        String lastRefundDate=creditLog.getLastRefundTime();
        try{
        String renewedBeginTime=TimeUtils.getDateAfterDays(lastRefundDate,1);
        slCreditRenewedVo.setRenewedBegintime(renewedBeginTime);
        }catch (Exception e){

        }
          return slCreditRenewedVo;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public String queryMerNameByJoinid(int joinid) throws BusinessException {
        return dao.queryMerNameByJoinid(joinid);  //To change body of implemented methods use File | Settings | File Templates.
    }
	
    @Override
    public Map<String, Object> initProcessRole(int id) throws BusinessException {
        String mchname=queryMerNameByJoinid(id);
        if(CommonUtils.isEmpty(mchname)){
            throw new BusinessException("查询保理公司的名称有误");
        }
        Map<String,Object> vars=new HashMap();
        vars.put("sl_user", "sl_user");
        if(mchname.contains("前海")){
            vars.put("sl_ywzy", "szqh_sl_ywzy");
            vars.put("sl_ywzg", "szqh_sl_ywzg");
            vars.put("sl_jl",   "szqh_sl_jl");
            vars.put("sl_cwzj", "szqh_sl_cwzj");
            vars.put("sl_fkzy", "szqh_sl_fkzy");
        }else if(mchname.contains("国华汇银")){
             if(mchname.contains("北京")){
                 vars.put("sl_ywzy", "ghbj_sl_ywzy");
                 vars.put("sl_ywzg", "ghbj_sl_ywzg");
                 vars.put("sl_jl",   "ghbj_sl_jl");
                 vars.put("sl_cwzj", "ghbj_sl_cwzj");
                 vars.put("sl_fkzy", "ghbj_sl_fkzy");
             }else{
                 vars.put("sl_ywzy", "ghsz_sl_ywzy");
                 vars.put("sl_ywzg", "ghsz_sl_ywzg");
                 vars.put("sl_jl",   "ghsz_sl_jl");
                 vars.put("sl_cwzj", "ghsz_sl_cwzj");
                 vars.put("sl_fkzy", "ghsz_sl_fkzy");
             }
        }else if(mchname.contains("18join测试")){
            vars.put("sl_ywzy", "test_blgs_ywzy");
            vars.put("sl_ywzg", "test_blgs_ywzg");
            vars.put("sl_jl",   "test_blgs_jl");
            vars.put("sl_cwzj", "test_blgs_cwzj");
            vars.put("sl_fkzy", "test_blgs_fkzy");
        }
        return vars;
    }
    
    @Override
    public Map<String, Object> initProcessRoleByAll() throws BusinessException {
        Map<String,Object> vars=new HashMap();
        vars.put("sl_user", "sl_user");
        
//        vars.put("sl_ywzy", "szqh_sl_ywzy,ghbj_sl_ywzy,ghsz_sl_ywzy");
//        vars.put("sl_ywzg", "szqh_sl_ywzg,ghbj_sl_ywzg,ghsz_sl_ywzg");
//        vars.put("sl_jl",   "szqh_sl_jl,ghbj_sl_jl,ghsz_sl_jl");
//        vars.put("sl_cwzj", "szqh_sl_cwzj,ghbj_sl_cwzj,ghsz_sl_cwzj");
//        vars.put("sl_user", "szqh_sl_user,ghbj_sl_user,ghsz_sl_user");
//        vars.put("sl_fkzy", "szqh_sl_fkzy,ghbj_sl_fkzy,ghsz_sl_fkzy");
        return vars;
    }
    
    public void updateMortgageInfo(int joinuserid,
			int mortgage_flag, 
            String mortgage_info) throws BusinessException {
		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setMortgageFlag(mortgage_flag);
		vo.setMortgageInfo(mortgage_info);
	}
    
	@Override
	public void refuseCredit(int liveid, int joinuserid, int loanstatus, String credittype,
			String returncredittype, int idOfTbMerchantUserOfCreditor, String memo, 
			String taskid, String processid, String pagets)
			throws BusinessException {
		//更新申请记录状态
//		updateLoanStatusAndMemoById(liveid, joinuserid, loanstatus, memo, pagets);
		
		validateservice.validateVO(liveid,
				new TbSlLoanApplication().getTableName(), pagets);

		TbSlLoanApplication vo = new TbSlLoanApplication();
		vo.setId(liveid);
		vo.setIdOfTbMerchantUser(joinuserid);
		vo.setMemo(memo);
		vo.setLoanstatus(loanstatus);
		
		//授信拒绝需要置授信状态，保证在一个流程实例内
		if (credittype.equals("0")) {
			vo.setCreditType(ISLConstDef.SLLOAN_CREDITTYPE_VAGUEREFUSE); 
		} else if (credittype.equals("1")) {
			vo.setCreditType(ISLConstDef.SLLOAN_CREDITTYPE_PRECISEREFUSE);
		}
		
		((TbSlLoanApplicationDao) this.getBaseDao()).updateByPrimaryIdAndJoinid(vo);
		
		//驱动授信流程
		Map<String,Object> taskVars = new HashMap();
		taskVars.put("pass", "0");
		TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(joinuserid);
		taskVars.put("title", infovo.getMchName());
//		if (credittype.equals("0")) {
//			taskVars.put("title", "模糊授信");
//		} else if (credittype.equals("1")) {
//			taskVars.put("title", "精准授信");
//		}
		
		String promemo = "";
		if (credittype.equals("0")) {
			promemo = "模糊授信不通过，拒绝原因：" + memo;
		} else if (credittype.equals("1")) {
			promemo = "精准授信不通过，拒绝原因：" + memo;
		}
		runYWZYBpmProcessByVar(idOfTbMerchantUserOfCreditor, taskid, processid, taskVars, promemo);
	}

	@Override
	public void refuseMaterial(int liveid, int joinuserid, int loanstatus, int idOfTbMerchantUserOfCreditor, 
			String memo, String taskid, String processid, String pagets) throws BusinessException {
		//更新申请记录状态
		updateLoanStatusAndMemoById(liveid, joinuserid, loanstatus, memo, pagets);
		
		Map<String,Object> taskVars = new HashMap();
		taskVars.put("pass", "0");
		TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(joinuserid);
		taskVars.put("title", infovo.getMchName());
		runYWZYBpmProcessByVar(idOfTbMerchantUserOfCreditor, taskid, processid, taskVars, "合同审核不通过, 拒绝原因：" + memo);	
	}

	@Override
	public void saveSLLoanCreditAggVO(TbSlLoanCreditAggVO aggvo, String taskid, String processid) throws BusinessException {
		try {
			if (StringUtils.isEmpty(aggvo.getShortname()))
				throw new BusinessException("商户简称不能为空.");
			
			if (aggvo.getApplyvo() == null)
				throw new BusinessException("通用授信信息不能为空.");
			
			if (aggvo.getPlatformuserList() == null || aggvo.getPlatformuserList().size() == 0)
				throw new BusinessException("电商平台授信信息不能为空.");
			
			//校验字段是否为空
			List<String> applyValidFieldNames = new ArrayList<String>();
			applyValidFieldNames.add("id");
			applyValidFieldNames.add("idOfTbMerchantUser");
			applyValidFieldNames.add("idOfTbMerchantUserOfCreditor");
			applyValidFieldNames.add("renewedServicefee");
			applyValidFieldNames.add("renewedFee");
			applyValidFieldNames.add("renewedRate");
//			applyValidFieldNames.add("creditEndDate");
			applyValidFieldNames.add("penalty");
			applyValidFieldNames.add("rowUpdateTime");
			applyValidFieldNames.add("yyzzExpireDate");
			List<Pair> applyValidBean = CommonUtils.beanValid(aggvo.getApplyvo(), applyValidFieldNames);
			if(CollectionUtils.isNotEmpty(applyValidBean)){
				throw new BusinessException((String) ((Pair)(applyValidBean.get(0))).second);
			}
			
			for(TbSlPlatformUserVO platformUserVO : aggvo.getPlatformuserList()) {
				//校验字段是否为空
				List<String> platformValidFieldNames = new ArrayList<String>();
				platformValidFieldNames.add("id");
				platformValidFieldNames.add("idOfTbMerchantUser");
				platformValidFieldNames.add("discount");
				platformValidFieldNames.add("rate");
				platformValidFieldNames.add("fee");
//				platformValidFieldNames.add("creditCertificate"); //0328 不用上传授信凭证
				platformValidFieldNames.add("maxAmount");
				platformValidFieldNames.add("loanPeriod");
				platformValidFieldNames.add("rowUpdateTime");
				platformValidFieldNames.add("contractExpireDate");
				List<Pair> platformValidBean = CommonUtils.beanValid(platformUserVO, platformValidFieldNames);
				if(CollectionUtils.isNotEmpty(platformValidBean)){
					throw new BusinessException((String) ((Pair)(platformValidBean.get(0))).second);
				}
			}
			
			updatePreciseCredit(aggvo.getShortname(), aggvo.getApplyvo());
			
			for(TbSlPlatformUserVO platformUserVO : aggvo.getPlatformuserList()) {
				platformuserService.updatePlatformUserCredit(platformUserVO);
			}
			
			if (taskid == null || processid == null)
				return;
			
			//驱动授信流程
			Map<String,Object> taskVars = new HashMap();
			taskVars.put("pass", "1");
			TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(aggvo.getApplyvo().getIdOfTbMerchantUser());
			taskVars.put("title", infovo.getMchName());
			runYWZYBpmProcessByVar(aggvo.getApplyvo().getIdOfTbMerchantUserOfCreditor(), taskid, processid, taskVars, "精准授信通过");
		} catch (Exception e) {
			if (e instanceof BusinessException)
				throw (BusinessException)e;
			
			LogUtils.getSlloanLog().error(e.getMessage());
			throw new BusinessException("更新用户所有授信信息出错,请检查.", e);
		}
	}

	@Override
	public void riskCreditRefuse(int liveid, int joinuserid, int idOfTbMerchantUserOfCreditor, 
			String memo, String taskid, String processid, String pagets) throws BusinessException {
		//更新申请记录状态
		updateLoanStatusAndMemoById(liveid, joinuserid, ISLConstDef.SLLOANSTATUS_RISKREFUSEED, memo, pagets);
		
		Map<String,Object> taskVars = new HashMap();
		taskVars.put("pass", "0");
		TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(joinuserid);
		taskVars.put("title", infovo.getMchName());
		runFKZYBpmProcessByVar(idOfTbMerchantUserOfCreditor, taskid, processid, taskVars, "风控复审不通过, 拒绝原因：" + memo);	
	}
	
	@Override
	public void riskCreditPassed(int liveid, int joinuserid, int idOfTbMerchantUserOfCreditor, String taskid, String processid, 
			String pagets) throws BusinessException {
		//更新申请记录状态
		updateLoanStatusAndMemoById(liveid, joinuserid, ISLConstDef.SLLOANSTATUS_RISKPASSED, null, pagets);
		
		Map<String,Object> taskVars = new HashMap();
		taskVars.put("pass", "1");
		TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(joinuserid);
		taskVars.put("title", infovo.getMchName());
		runFKZYBpmProcessByVar(idOfTbMerchantUserOfCreditor, taskid, processid, taskVars, "风控复审通过");	
	}

    @Override
    public void queryNeedMessage() throws BusinessException {
          if(CommonUtils.isDev())
        	  return;
          
          List<TbSlLoanApplicationInfoVO> list=((TbSlLoanApplicationDao) this.getBaseDao()).queryNeedMessage();
          if(CommonUtils.isEmpty(list))
        	  return;
          
          for(TbSlLoanApplicationInfoVO vo:list){
          String mobile=vo.getMobile();
              if(!CommonUtils.isEmpty(mobile)){
            	  NotificationTemplate template = notificationTemplateService.findByName(ISLConstDef.CONTRACT_EXPIRE);
            	  if (template == null || StringUtils.isEmpty(template.getTemplate()))
            		  return;
            	  
              SMSSendUtil.sendMsg(mobile,template.getTemplate());
              }
          }

    }

    @Override
	public void updatePreciseCredit(String shortname, TbSlLoanApplication vo
            ) throws BusinessException {
		LogUtils.getSlloanLog().info(
				"供应链贷款精准授信. " + BeanMapUtils.getString(vo));
		validateservice.validateVO(vo.getId(),
				new TbSlLoanApplication().getTableName(), vo.getRowUpdateTime());

		TbSlLoanApplication dbvo = this.queryTbSlApplicationByID(vo.getId());
		//如果该申请记录已通过保理合同审核则不做状态变更，否则更新为已精准授信
		if(dbvo.getLoanstatus() != ISLConstDef.SLLOANSTATUS_MATERIALPASSED) {
			vo.setLoanstatus(ISLConstDef.SLLOANSTATUS_CREDITED);
			vo.setCreditType(ISLConstDef.SLLOAN_CREDITTYPE_PRECISE);
		}
		
		//更新精准授信信息
		((TbSlLoanApplicationDao) this.getBaseDao()).updateByPrimaryIdAndJoinid(vo);
		
		//更新商户简称
		userservice.updateShortnameById(vo.getIdOfTbMerchantUser(), shortname);
	}

	private void runBpmProcessByVar(int idOfTbMerchantUserOfCreditor, String taskid, String processid, Map<String,Object> taskVars, String lastfix, String memo) {
		TbMerchantUser operatorvo = userservice.queryById(idOfTbMerchantUserOfCreditor);
		if (operatorvo == null || StringUtils.isEmpty(operatorvo.getShortname()))
			throw new BusinessException("保理公司为空或保理公司简称为空，请检查.");
		
		try{
            memo= URLDecoder.decode(memo, Constants.ENCODING);
        }catch(Exception e){
        }
//		String rolename = StringUtils.lowerCase(operatorvo.getShortname() + "_sl_" + lastfix); //例如：szqh_sl_ywzy
//		String userId = UserUtils.getUser().getLoginName();
		//根据放款用户查询对应的保理公司的风控专员角色code，再根据此code查询taskid和processid
//		Task taskYWZY = taskService.createTaskQuery().processDefinitionId(ISLConstDef.creditProcessDefinitionId).taskAssignee(userId).active().singleResult();
		bpmTaskService.complete(taskid, processid, memo, taskVars);
	}

	private void runFKZYBpmProcessByVar(int idOfTbMerchantUserOfCreditor, String taskid, String processid, Map<String,Object> taskVars, String memo) {
		runBpmProcessByVar(idOfTbMerchantUserOfCreditor, taskid, processid, taskVars, "fkzy", memo);
	}
	
	private void runYWZYBpmProcessByVar(int idOfTbMerchantUserOfCreditor, String taskid, String processid, Map<String,Object> taskVars, String memo) {
		runBpmProcessByVar(idOfTbMerchantUserOfCreditor, taskid, processid, taskVars, "ywzy", memo);
	}


	@Override
	public String querySLLoanAppProcInstIdById(int id) throws BusinessException {
		return ((TbSlLoanApplicationDao) this.getBaseDao()).querySLLoanAppProcInstIdById(id);
	}

	@Override
	public void updateLoanStatusAndProcessStatus(Integer credittype, int joinuserid, int slloanid, 
			List<TbSlPlatformUser> entitys) throws BusinessException {
        try {
        	((TbSlLoanApplicationService) AopContext.currentProxy()).updateLoanStatusById(joinuserid, ISLConstDef.SLLOANSTATUS_DOING);
        	
        	//未授信过才需要新起流程实例
            String processid = null;
            if (null == credittype) {
    			String loginName = CommonUtils.getPrincipal().getLoginName();
    			Map<String,Object> vars=new HashMap();
    		    vars.put("sl_user", "sl_user");
    			vars.put("sl_ywzy", "szqh_sl_ywzy,test_blgs_ywzy");
    			vars.put("sl_fkzy", "szqh_sl_fkzy,test_blgs_fkzy");

    			ProcessMessageVO processvo = new ProcessMessageVO();
    			processvo.setProcDefKey(ISLConstDef.creditProcessDefinitionKey);
    			processvo.setBusinessTable("tb_sl_loan_application");
    			processvo.setBusinessId(slloanid + "");
    			processvo.setLoginName(loginName);
    			processvo.setTitle("启动授信流程");
    			processvo.setVars(vars);
    	
    			processid = bpmTaskService.startProcess(processvo.getProcDefKey(),
    					processvo.getBusinessTable(), 
    					processvo.getBusinessId(),
    					processvo.getTitle(),
    					processvo.getLoginName(), 
    					processvo.getVars());
    	
            }
            
			//用户提交资料
        	if (StringUtils.isEmpty(processid))
        		processid = ((TbSlLoanApplicationService) AopContext.currentProxy()).querySLLoanAppProcInstIdById(slloanid);
        	
        	Task taskUSER = taskService.createTaskQuery().processDefinitionKey(ISLConstDef.creditProcessDefinitionKey).processInstanceId(processid).singleResult();
        	List<Task> tasklist = taskService.createTaskQuery().processDefinitionKey(ISLConstDef.creditProcessDefinitionKey).taskCandidateUser("sl_user").list();
        	if (tasklist != null && tasklist.size() > 0) {
				bpmTaskService.claim(taskUSER.getId(), "sl_user");
        	}
            
			List<TbSlPlatformUserVO> platforms = platformuserService.selectAllPlatformUserListByJoinID(joinuserid, null);
			Map<String, Object> taskVars = new HashMap();
			if (CollectionUtils.isEmpty(entitys) && CollectionUtils.isEmpty(platforms)) {
				taskVars.put("credittype", "0");
			} else {
				taskVars.put("credittype", "1");
			}
			TbMerchantInfo infovo = merchantinfoservice.queryInfoByJoinId(joinuserid);
			taskVars.put("title", infovo.getMchName());
			
			bpmTaskService.complete(taskUSER.getId(), taskUSER.getProcessInstanceId(), "用户申请", taskVars);
        } catch (Exception e) {
        	LogUtils.error(log, e);
        	throw new BusinessException("授信流程启动失败，请联系管理员.");
        }	
	}


    @Override
    public List<TbApplicationExpireVo> queryApplicationExpireForOperator(Pageable page) throws BusinessException {

        List<TbApplicationExpireVo> list=((TbSlLoanApplicationDao) this.getBaseDao()).queryTbApplicationExpireVo(page);
        if(CommonUtils.isEmpty(list)){
            return null;
        }
        for(TbApplicationExpireVo vo:list){
            List<TbPlatformExpireVo> platformExpireVoList=platformuserService.queryTbPlatformExpire(vo.getIdOfTbMerchantUser());
            vo.setTbPlatformExpireVoList(platformExpireVoList);
        }
       return list;
    }


	@Override
	public void updateYYZZexpiredDate(int joinuserid, String expiredDate) throws BusinessException {
		TbSlLoanApplication tbsl=new TbSlLoanApplication();
		tbsl.setIdOfTbMerchantUser(joinuserid);
		tbsl.setYyzzExpireDate(expiredDate);
		dao.updateByJoinid(tbsl);
		
	}


	@Override
	public void updateBLHTexpiredDate(int joinuserid, String expiredDate) throws BusinessException {
		TbSlLoanApplication tbsl=new TbSlLoanApplication();
		tbsl.setIdOfTbMerchantUser(joinuserid);
		tbsl.setCreditEndDate(expiredDate);
		dao.updateByJoinid(tbsl);
		
	}


}

